#include "stdafx.h"
#include "../EdgeMath/Vectors.h"
#include "VertexFormats.h"
#include "GraphicsManager.h"
#include "VertexLayout_VERTEX.csh"
#include "VertexLayout_VERTEXTEX.csh"
#include "VertexLayout_VERTEXCOLOR.csh"
#include "VertexLayout_VERTEXNORMALTEXTURE.csh"
#include "VertexLayout_VERTEXNORMALTEXTURETANGENT.csh"


using namespace std;

using namespace VertexFormats;

#pragma region Vertex
Vertex::Vertex(void)
{
	position = { 0.f, 0.f, 0.f };
}

Vertex::Vertex(float3& position)
{
	this->position = position;
}

/*static*/ ID3D11InputLayout* Vertex::getInputLayout(void)
{
	D3D11_INPUT_ELEMENT_DESC input;
	ZeroMemory(&input, sizeof(D3D11_INPUT_ELEMENT_DESC));

	input.SemanticName = "POSITION";
	input.SemanticIndex = 0;
	input.Format = DXGI_FORMAT_R32G32B32_FLOAT;
	input.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	input.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;	

	return GraphicsManager::GetInstance()->createInputLayout(&input, VertexLayout_VERTEX, sizeof(VertexLayout_VERTEX), 1);
}
#pragma endregion

#pragma region VertexTexture

VertexTexture::VertexTexture(void)
{
	memset(this, 0, sizeof(VertexTexture));
}

VertexTexture::VertexTexture(float3& position, float2& texCoord)
{
	this->position = position;
	this->texCoord = texCoord;
}

/*virtual*/ ID3D11InputLayout* VertexTexture::getInputLayout(void) /*override*/
{
	D3D11_INPUT_ELEMENT_DESC layout[2];
	ZeroMemory(&layout, sizeof(D3D11_INPUT_ELEMENT_DESC) * 2);

	layout[0].SemanticName = "POSITION";
	layout[0].SemanticIndex = 0;
	layout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[0].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	layout[1].SemanticName = "TEXCOORD";
	layout[1].SemanticIndex = 0;
	layout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	return GraphicsManager::GetInstance()->createInputLayout(layout, VertexLayout_VERTEXTEX, sizeof(VertexLayout_VERTEXTEX), 2);
}

#pragma endregion

#pragma region VertexNormalTexture
VertexNormalTexture::VertexNormalTexture(void)
{
	memset(this, 0, sizeof(VertexNormalTexture));
}

VertexNormalTexture::VertexNormalTexture(float3& position, float2& texCoord, float3& normal)
{
	this->position = position;
	this->texCoord = texCoord;
	this->normal = normal;
}


/*static*/ ID3D11InputLayout* VertexNormalTexture::getInputLayout(void)
{
	D3D11_INPUT_ELEMENT_DESC layout[3];
	ZeroMemory(&layout, sizeof(D3D11_INPUT_ELEMENT_DESC) * 3);

	layout[0].SemanticName = "POSITION";
	layout[0].SemanticIndex = 0;
	layout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[0].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	layout[1].SemanticName = "NORMAL";
	layout[1].SemanticIndex = 0;
	layout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	layout[2].SemanticName = "TEXCOORD";
	layout[2].SemanticIndex = 0;
	layout[2].Format = DXGI_FORMAT_R32G32_FLOAT;
	layout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	return GraphicsManager::GetInstance()->createInputLayout(layout, VertexLayout_VERTEXNORMALTEXTURE, sizeof(VertexLayout_VERTEXNORMALTEXTURE), 3);
}
#pragma endregion

#pragma region VertexColor


VertexColor::VertexColor(void)
{
	memset(this, 0, sizeof(VertexColor));
}

VertexColor::VertexColor(float3& position, float4& color)
{
	this->position = position;
	this->color = color;
}

/*static*/ ID3D11InputLayout* VertexColor::getInputLayout(void)
{
	D3D11_INPUT_ELEMENT_DESC layout[2];
	ZeroMemory(&layout, sizeof(D3D11_INPUT_ELEMENT_DESC) * 2);

	layout[0].SemanticName = "POSITION";
	layout[0].SemanticIndex = 0;
	layout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[0].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	layout[1].SemanticName = "COLOR";
	layout[1].SemanticIndex = 0;
	layout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	layout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	
	return GraphicsManager::GetInstance()->createInputLayout(layout, VertexLayout_VERTEXCOLOR, sizeof(VertexLayout_VERTEXCOLOR), 2);
}

#pragma endregion

#pragma region VertexPositionNormalTangent

VertexNormalTextureTangent::VertexNormalTextureTangent(void)
{
	memset(this, 0, sizeof(VertexNormalTextureTangent));
}

VertexNormalTextureTangent::VertexNormalTextureTangent(float3& position, float3& normal, float3& tangent, float2& texCoord)
{
	this->position = position;
	this->normal = normal;
	this->tangent = tangent;
	this->texCoord = texCoord;
}

/*static*/ ID3D11InputLayout* VertexNormalTextureTangent::getInputLayout(void)
{
	D3D11_INPUT_ELEMENT_DESC layout[4];
	ZeroMemory(&layout, sizeof(D3D11_INPUT_ELEMENT_DESC) * 4);

	layout[0].SemanticName = "POSITION";
	layout[0].SemanticIndex = 0;
	layout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[0].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	layout[1].SemanticName = "NORMAL";
	layout[1].SemanticIndex = 0;
	layout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	layout[2].SemanticName = "TANGENT";
	layout[2].SemanticIndex = 0;
	layout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	layout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;	

	layout[3].SemanticName = "TEXCOORD";
	layout[3].SemanticIndex = 0;
	layout[3].Format = DXGI_FORMAT_R32G32_FLOAT;
	layout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	layout[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;

	return GraphicsManager::GetInstance()->createInputLayout(layout, VertexLayout_VERTEXNORMALTEXTURETANGENT, sizeof(VertexLayout_VERTEXNORMALTEXTURETANGENT), 4);
}

#pragma endregion
